package ua.soso.dao.util;

import org.aopalliance.aop.Advice;
import org.aspectj.lang.JoinPoint;
import org.hibernate.HibernateException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DataAccessException;
import org.springframework.orm.hibernate3.SessionFactoryUtils;

public class HibernateDaoAdvice implements Advice {
    private static final Logger LOG = LoggerFactory.getLogger(HibernateDaoAdvice.class);

    /**
     * Converts {@link HibernateException} to corresponding {@link DataAccessException}.
     *
     * @param e thrown exception.
     * @throws DataAccessException converted exception.
     * @see SessionFactoryUtils
     */
    public void convertHibernateException(HibernateException e) throws DataAccessException {
        LOG.trace("HibernateException has been thrown: {}", e.getMessage(), e);

        throw SessionFactoryUtils.convertHibernateAccessException(e);
    }

    /**
     * Method adds logging to profile DAO method invocations. Requires TRACE log level enabled for performing logging at all.
     *
     * @param jp join point of the advice. Required for determine target class, method and passed arguments.
     */
    public void beforeMethod(JoinPoint jp) {
        if (LOG.isTraceEnabled()) {
            StringBuilder pattern = new StringBuilder("Invocation of the ");

            pattern.append(jp.getTarget().getClass().getName());
            pattern.append('.');
            pattern.append(jp.getSignature().getName());
            pattern.append('(');

            for (Object obj : jp.getArgs()) {
                pattern.append("`").append(obj).append("`");
            }

            pattern.append(')');

            LOG.trace(pattern.toString());
        }
    }
}
